package utils

import (
	"math/rand"
	"sync"
	"time"
)

type ID struct {
	//ids map[uint8]struct{}
	ids *sync.Map
}

func NewID() *ID {
	return &ID{
		ids: &sync.Map{},
	}
}

func (i *ID) Get() uint8 {
	randSource := rand.NewSource(time.Now().UnixNano())
	randGenerator := rand.New(randSource)
	for {
		randomNum := uint8(randGenerator.Intn(255) + 1)

		if _, ok := i.ids.Load(randomNum); !ok {
			i.ids.Store(randomNum, nil)
			return randomNum
		}
	}
}

func (i *ID) GetUInt64() uint64 {
	randSource := rand.NewSource(time.Now().UnixNano())
	randGenerator := rand.New(randSource)
	for {
		randomNum := randGenerator.Uint64()

		if _, ok := i.ids.Load(randomNum); !ok {
			i.ids.Store(randomNum, nil)
			return randomNum
		}
	}
}

func (i *ID) Len() int {
	var len int
	i.ids.Range(func(key, value any) bool {
		k := key.(uint8)
		if k > 0 {
			len++
		}
		return true
	})
	return len
}

func (i *ID) Release(d uint8) {
	i.ids.Delete(d)
}
